﻿using System;
using System.Collections.Generic;
using System.Text;
using Sora.Data;
using Sora.HelpSystem.Package.DataObjects;
using System.Windows.Documents;

namespace Sora.HelpSystem.Package.Pages
{
    public class HelpPage : HelpPagesRepository.TreeItemObject
    {
        internal IEntry InternalKey
        {
            get { return Key; }
        }

        public HelpDocument Document
        {
            get { return ((HelpPagesRepository)Container).Document; }
        }

        public HelpPage(HelpPagesRepository container, IEntry key)
            : base(container, key)
        {
            if (ReadOnly)
            {
                if (!Key.PropertyExists("FlowContent"))
                    FlowContent = new FloatingFlowDocumentProperty(new FlowDocument());
                else
                    FlowContent = new CachedFlowDocumentProperty(Key.Property("FlowContent"));
            }
            else
                FlowContent = new CachedFlowDocumentProperty(Key.Property("FlowContent"));
        }

        public ICachedFlowDocumentProperty FlowContent { get; private set; }

        public Uri UriContent
        {
            get { return Get<Uri>("UriContent", null); }
            set { Set("UriContent", value); }
        }

        public ContentType ContentType
        {
            get { return Get<ContentType>("ContentType", ContentType.FlowContent); }
            set { Set<ContentType>("ContentType", value); }
        }

        public int Order
        {
            get { return Get<int>("Order", 0); }
            set { Set<int>("Order", value); }
        }

        public string PageTitle
        {
            get { return Get<string>("PageTitle"); }
            set
            {
                Set("PageTitle", value);
                RaisePropertyChanged("");
            }
        }

        public string SafePageTitle
        {
            get
            {
                return String.IsNullOrEmpty(PageTitle) ? Name : PageTitle;
            }
        }

        public bool IsSummaryVisible
        {
            get { return Get("IsSummaryVisible", true); }
            set { Set("IsSummaryVisible", value); }
        }

        public string Name
        {
            get { return Key.Name; }
            set
            {
                Key.Name = value;

                RaisePropertyChanged("Name");

                /* Si l'uri est modifiée, ça change aussi l'uri des enfants */
                RecursiveNotifyUriChange(this);
            }
        }

        private void RecursiveNotifyUriChange(HelpPage page)
        {
            page.RaisePropertyChanged("Uri");

            foreach (var child in page.Children)
                RecursiveNotifyUriChange(child);
        }

        public Uri Uri
        {
            get
            {
                var current = this;
                string uri = String.Empty;

                while (current != null && !((HelpPagesRepository)Container).IsRootKey(current))
                {
                    uri = current.Key.Name + (String.IsNullOrEmpty(uri) ? String.Empty : ("/" + uri));

                    current = ((HelpPagesRepository)Container).LoadInternalObject(current.InternalKey.Parent);
                }

                uri = HelpDocument.HelpDocumentUriContentPrefix + "/" + uri;

                return new Uri(uri);
            }
        }

        public HelpPage Parent
        {
            get
            {
                if (((HelpPagesRepository)Container).IsRootKey(this))
                    return null;
                else
                    return ((HelpPagesRepository)Container).LoadInternalObject(Key.Parent);
            }
        }

        public override void Delete()
        {
            var parent = Parent;
            
            base.Delete();

            if (parent != null)
                parent.NotifyItemsChange();
        }

        public override HelpPage Child(string path)
        {
            return Child(path, !ReadOnly);
        }

        public override HelpPage Child(string path, bool canCreate)
        {
            var existed = !canCreate || ChildExists(path); /* canCreate juste pour ne pas faire le ChildExists s'il faut false */
            
            var result = base.Child(path, canCreate);
            
            if (result != null && !existed)
            {
                if (!existed)
                    NotifyItemsChange();
            }

            return result;
        }

        private void NotifyItemsChange()
        {
            RaisePropertyChanged("ChildNames");
            RaisePropertyChanged("Children");
        }
    }
}
